public class Task extends Processor {
    static Task first = null;
    static Task current = null;
    static Task tmp;
    Task next;  // 'next' *MUST* be the first instance variable!
    long timer; // 'timer' *must* follow 'next'
    long PC;    // 'PC' *must* follow 'timer'

    public static void run() {
	current = first;

	_asm("    banksel _OPTION");
	_asm("    bcf     _OPTION,5"); // clock src = clkout
	_asm("    bcf     _OPTION,3"); // prescaler assigned to timer0

	_asm("    set_prescaler_for_1ms");

	_asm("    banksel _INTCON");
	_asm("    bcf     _INTCON,2"); // clear overflow flag
	_asm("    bsf     _INTCON,5"); // enable tmr0 ints
	_asm("    bsf     _INTCON,7"); // enable global ints

	_asm("    goto    Task_schedule__V");
    }

    public Task(String startAddress) {
	next = first;
	first = this;
	timer = 0;
    }

    public static void sleep(long tmo) {
    }

    static void schedule() {
	_asm("    banksel Task_current");
	_asm("scheduleloop");
	_asm("    clrwdt");

	_asm("    movf    Task_current,0");
	_asm("    movwf   4");
	_asm("    movf    0,0"); // next task in W
	_asm("    btfsc   _STATUS,_Z");
	_asm("    movf    Task_first,0");
	_asm("    movwf   Task_current");

	_asm("    movwf   4"); // FSR = current
	_asm("    incf    4,1"); // fsr = current.timer high
	_asm("    movf    0,0");
	_asm("    btfss   _STATUS,_Z"); // timer high == 0
	_asm("    goto    scheduleloop");

	_asm("    incf    4,1"); // fsr = current.timer low
	_asm("    movf    0,0");
	_asm("    btfss   _STATUS,_Z"); // timer low == 0
	_asm("    goto    scheduleloop");

	_asm("    incf    4,1"); // fsr = current.PC high
	_asm("    movf    0,0");
	_asm("    movwf   _PCLATH");
	_asm("    incf    4,1"); // fsr = current.PC low
	_asm("    movf    0,0");
	_asm("    movwf   _PCL");
    }

    static void interrupt() {
	_asm("    movf    Task_first,0");
	_asm("    movwf   Task_tmp");

	_asm("Task_loop");
	_asm("    movf    Task_tmp,0");
	_asm("    btfsc   _STATUS,_Z");
	_asm("    goto    Task_end");

	_asm("    movwf   4"); // task.next
	_asm("    movf    0,0");
	_asm("    movwf   Task_tmp"); // tmp = tmp.next

	_asm("    incf    4,1");
	_asm("    movf    0,0");
	_asm("    btfss   _STATUS,_Z"); // timer high == 0
	_asm("    goto    Task_decrement");

	_asm("    incf    4,1"); // fsr = current.timer low
	_asm("    movf    0,0");
	_asm("    btfss   _STATUS,_Z"); // timer low == 0
	_asm("    decf    0,1");
	_asm("    goto    Task_loop");

	_asm("Task_decrement");
	_asm("    incf    4,1"); // fsr = current.timer low
	_asm("    decf    0,1");
	_asm("    movf    0,0");
	_asm("    sublw   255");
	_asm("    btfss   _STATUS,_Z");
	_asm("    goto    Task_loop");
	_asm("    decf    4,1");
	_asm("    decf    0,1");
	_asm("    goto    Task_loop");
	_asm("Task_end");

	_asm("    movlw   tmr0_for_1ms");
	_asm("    movwf   _TMR0");

	_asm("    bcf     _INTCON,2");
	_asm("    bsf     _INTCON,5");
    }
}
